/**
 * 
 */
package fr.univ_tln.inf9.exaplanning.api.facade;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.swing.event.EventListenerList;

import fr.univ_tln.inf9.exaplanning.api.administration.Administrator;
import fr.univ_tln.inf9.exaplanning.api.composante.Component;
import fr.univ_tln.inf9.exaplanning.api.facade.event.AdminAddedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.AdminRemovedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.BuildingAddedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.BuildingRemovedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ComponentAddedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ComponentRemovedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListAdminChangedEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListAdminListener;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListBuildingChangedEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListBuildingListener;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListComponentChangedEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListComponentListener;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListStudentChangedEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListStudentListener;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListTeacherChangedEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.ListTeacherListener;
import fr.univ_tln.inf9.exaplanning.api.facade.event.StudentAddedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.StudentRemovedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.TeacherAddedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.facade.event.TeacherRemovedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.salle.Building;
import fr.univ_tln.inf9.exaplanning.api.salle.event.ListRoomChangedEvent;
import fr.univ_tln.inf9.exaplanning.api.salle.event.ListRoomListener;
import fr.univ_tln.inf9.exaplanning.api.salle.event.Position_xListener;
import fr.univ_tln.inf9.exaplanning.api.salle.event.Position_yListener;
import fr.univ_tln.inf9.exaplanning.api.salle.event.RoomAddedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.utilisateur.Student;
import fr.univ_tln.inf9.exaplanning.api.utilisateur.Teacher;

/**
 * @author pivi
 *
 */
public class University {

	
	
	 /**
     * Ici les listes que la fçade gère
     */
    
    private List<String> lteach = new LinkedList<String>();
    private List<String> lstudent = new LinkedList<String>();
    private List<String> lbuilding = new LinkedList<String>();
    private List<String> ladmin = new LinkedList<String>();
    private List<String> lcomponent = new LinkedList<String>();
    
    private EventListenerList listeners;
    /**
     * Constructor par défaut
     */
    public University() {
            super();
            listeners = new EventListenerList();
    }

	/**
	 * @return the lteach
	 */
	public List<String> getLteach() {
		return lteach;
	}

	/**
	 * ici fire alerte que la liste de professeur a changé
	 * @param lteach the lteach to set
	 */
	public void setLteach(List<String> lteach) {
		this.lteach = lteach;
		fireListTeachChanged();
	}

	

	/**
	 * @return the lstudent
	 */
	public List<String> getLstudent() {
		return lstudent;
	}

	/**
	 * fire alerte que la liste étudiante a changé
	 * @param lstudent the lstudent to set
	 */
	public void setLstudent(List<String> lstudent) {
		this.lstudent = lstudent;
		fireListStudentChanged();
	}

	

	/**
	 * @return the lbuilding
	 */
	public List<String> getLbuilding() {
		return lbuilding;
	}

	/**
	 * fire alerte que la liste building a changé
	 * @param lbuilding the lbuilding to set
	 */
	public void setLbuilding(List<String> lbuilding) {
		this.lbuilding = lbuilding;
		fireListBuildingChanged();
	}

	

	/**
	 * @return the ladmin
	 */
	public List<String> getLadmin() {
		return ladmin;
	}

	/**
	 * fire alerte que la liste admin a changé
	 * @param ladmin the ladmin to set
	 */
	public void setLadmin(List<String> ladmin) {
		this.ladmin = ladmin;
		fireListAdminChanged();
	}



	/**
	 * @return the lcomponent
	 */
	public List<String> getLcomponent() {
		return lcomponent;
	}

	/**
	 * fire alerte que la liste component a changé
	 * @param lcomponent the lcomponent to set
	 */
	public void setLcomponent(List<String> lcomponent) {
		this.lcomponent = lcomponent;
		fireListComponentChanged();
	}

	

	/**
	 * @param t
	 * @return
	 * @see java.util.List#add(java.lang.Object)
	 * fire alerte qu'un élément a été rajouté à  la liste de prof
	 */
	public boolean addTeach(Teacher t) {
		boolean res =  lteach.add(t.getMail());
		fireAddTeacherToList(t.getMail());
		return res;
	}

	
	/**
	 * @param arg0
	 * @return
	 * @see java.util.List#remove(java.lang.Object)
	 * fire alerte qu'un élément a été supprimer de la liste de prof
	 */
	public boolean removeTeach(Object arg0) {
		boolean res = lteach.remove(arg0);
		fireRemoveTeacherToList(arg0.toString());
		return res;
	}

	

	/**
	 * @param t
	 * @return
	 * @see java.util.List#add(java.lang.Object)
	 * fire alerte qu'un élément a été rajouté à  la liste d'étudiant
	 */
	public boolean addStudent(Student s) {
		boolean res =  lstudent.add(s.getMail());
		fireAddStudentToList(s.getMail());
		return res;
	}


	/**
	 * @param arg0
	 * @return
	 * @see java.util.List#remove(java.lang.Object)
	 * fire alerte qu'un élément a été supprimer de la liste d'étudiant
	 */
	public boolean removeStudent(Object arg0) {
		boolean res = lstudent.remove(arg0);
		fireRemoveStudentToList(arg0.toString());
		return res;
	}


	/**
	 * @param b
	 * @return
	 * @see java.util.List#add(java.lang.Object)
	 * fire alerte qu'un élément a été ajouté à la liste de batiment
	 */
	public boolean addBuilding(Building b) {
		boolean res =  lbuilding.add(b.getName());
		fireAddTBuildingToList(b.getName());
		return res;
	}


	/**
	 * @param arg0
	 * @return
	 * @see java.util.List#remove(java.lang.Object)
	 * fire alerte qu'un élément a été supprimer de la liste de batiment
	 */
	public boolean removeBuilding(Object arg0) {
		boolean res = lbuilding.remove(arg0);
		fireRemoveBuildingToList(arg0.toString());
		return res;
	}


	/**
	 * @param a
	 * @return
	 * @see java.util.List#add(java.lang.Object)
	 * fire alerte qu'un élément a été ajouté à la liste d'administrateur
	 */
	public boolean addAdmin(Administrator a) {
		boolean res =  ladmin.add(a.getEmail());
		fireAddAdminToList(a.getEmail());
		return res;
	}


	/**
	 * @param arg0
	 * @return
	 * @see java.util.List#remove(java.lang.Object)
	 * fire alerte qu'un élément a été supprimer à la liste d'administrateur
	 */
	public boolean removeAdmin(Object arg0) {
		boolean res = ladmin.remove(arg0);
		fireRemoveAdminToList(arg0.toString());
		return res;
	}

	/**
	 * @param c
	 * @return
	 * @see java.util.List#add(java.lang.Object)
	 * fire alerte qu'un élément a été ajouté à la liste de composante
	 */
	public boolean addComponent(Component c) {
		boolean res =  lcomponent.add(c.getName());
		fireAddComponentToList(c.getName());
		return res;
	}

	

	/**
	 * @param arg0
	 * @return
	 * @see java.util.List#remove(java.lang.Object)
	 * fire alerte qu'un élément a été supprimé à la liste de composante
	 */
	public boolean removeComponent(Object arg0) {
		boolean res = lcomponent.remove(arg0);
		fireRemoveComponentToList(arg0.toString());
		return res;
	}


	

	/****************************************************************************************************************/
	/****************************************			LISTENER				*************************************/
	/****************************************************************************************************************/

	
	
	/**
	 * Listeners sur la liste de professeur
	 */
	public void AddListTeacherListener (ListTeacherListener listener){
		listeners.add(ListTeacherListener.class, listener);
	}
	
	public void RemoveListTeacherListener (ListTeacherListener listener){
		listeners.remove(ListTeacherListener.class, listener);
	}
    
	/**
	 * Listeners sur la liste de étudiant
	 */
	
	public void AddListStudentListener (ListStudentListener listener){
		listeners.add(ListStudentListener.class, listener);
	}
	
	public void RemoveListStudentListener (ListStudentListener listener){
		listeners.remove(ListStudentListener.class, listener);
	}
	
	/**
	 * Listeners sur la liste de batiment
	 */
	public void AddListBuildingListener (ListBuildingListener listener){
		listeners.add(ListBuildingListener.class, listener);
	}
	
	public void RemoveListBuildingListener (ListBuildingListener listener){
		listeners.remove(ListBuildingListener.class, listener);
	}
	
	
	/**
	 * Listeners sur la liste d'administrateur
	 */
	public void AddListAdminListener (ListAdminListener listener){
		listeners.add(ListAdminListener.class, listener);
	}
	
	public void RemoveListAdminListener (ListAdminListener listener){
		listeners.remove(ListAdminListener.class, listener);
	}
	
	
	/**
	 * Listeners sur la liste de composante
	 */
	public void AddListComponentListener (ListComponentListener listener){
		listeners.add(ListComponentListener.class, listener);
	}
	
	public void RemoveListComponentListener (ListComponentListener listener){
		listeners.remove(ListComponentListener.class, listener);
	}
	
	
	
										/*************************/
										/** Définition des fires**/
										/*************************/

	private void fireListTeachChanged() {
		ListTeacherListener[] listenerList = (ListTeacherListener[])listeners.getListeners(ListTeacherListener.class);
		
		for(ListTeacherListener listener : listenerList){
			listener.ListTeacherChanged(new ListTeacherChangedEvent(this, getLteach()));
		}
		
	}
	
	private void fireListStudentChanged() {
		ListStudentListener[] listenerList = (ListStudentListener[])listeners.getListeners(ListStudentListener.class);
		
		for(ListStudentListener listener : listenerList){
			listener.ListStudentChanged(new ListStudentChangedEvent(this, getLstudent()));
		}
		
	}
	
	private void fireListBuildingChanged() {
		ListBuildingListener[] listenerList = (ListBuildingListener[])listeners.getListeners(ListBuildingListener.class);
		
		for(ListBuildingListener listener : listenerList){
			listener.ListBuildingChanged(new ListBuildingChangedEvent(this, getLbuilding()));
		}
		
	}
	
	private void fireListAdminChanged() {
		ListAdminListener[] listenerList = (ListAdminListener[])listeners.getListeners(ListAdminListener.class);
		
		for(ListAdminListener listener : listenerList){
			listener.ListAdminChanged(new ListAdminChangedEvent(this, getLadmin()));
		}
		
	}

	private void fireListComponentChanged() {
		ListComponentListener[] listenerList = (ListComponentListener[])listeners.getListeners(ListComponentListener.class);
		
		for(ListComponentListener listener : listenerList){
			listener.ListComponentChanged(new ListComponentChangedEvent(this, getLcomponent()));
		}
		
		
	}

	private void fireAddTeacherToList(String mail) {
		ListTeacherListener[] listenerList = (ListTeacherListener[])listeners.getListeners(ListTeacherListener.class);
		
		for(ListTeacherListener listener : listenerList){
			listener.TeacherAddedToList(new TeacherAddedToListEvent(this, mail));
		}
		
		
	}
	
	private void fireRemoveTeacherToList(String string) {
		ListTeacherListener[] listenerList = (ListTeacherListener[])listeners.getListeners(ListTeacherListener.class);
		
		for(ListTeacherListener listener : listenerList){
			listener.TeacherRemovedToList(new TeacherRemovedToListEvent(this, string));
		}
		
		
	}

	private void fireAddStudentToList(String mail) {
		ListStudentListener[] listenerList = (ListStudentListener[])listeners.getListeners(ListStudentListener.class);
		
		for(ListStudentListener listener : listenerList){
			listener.StudentAddedToList(new StudentAddedToListEvent(this, mail));
		}
		
	}
	
	private void fireRemoveStudentToList(String string) {
		ListStudentListener[] listenerList = (ListStudentListener[])listeners.getListeners(ListStudentListener.class);
		
		for(ListStudentListener listener : listenerList){
			listener.StudentRemovedToList(new StudentRemovedToListEvent(this, string));
		}
		
	}
	
	private void fireAddTBuildingToList(String name) {
		ListBuildingListener[] listenerList = (ListBuildingListener[])listeners.getListeners(ListBuildingListener.class);
		
		for(ListBuildingListener listener : listenerList){
			listener.BuildingAddedToList(new BuildingAddedToListEvent(this, name));
		}
		
		
	}
	
	private void fireRemoveBuildingToList(String string) {
		ListBuildingListener[] listenerList = (ListBuildingListener[])listeners.getListeners(ListBuildingListener.class);
		
		for(ListBuildingListener listener : listenerList){
			listener.BuildingRemovedToList(new BuildingRemovedToListEvent(this, string));
		}
		
		
	}
	
	private void fireAddAdminToList(String name) {
		ListAdminListener[] listenerList = (ListAdminListener[])listeners.getListeners(ListAdminListener.class);
		
		for(ListAdminListener listener : listenerList){
			listener.AdminAddedToList(new AdminAddedToListEvent(this, name));
		}
		
		
	}
	
	private void fireRemoveAdminToList(String string) {
		ListAdminListener[] listenerList = (ListAdminListener[])listeners.getListeners(ListAdminListener.class);
		
		for(ListAdminListener listener : listenerList){
			listener.AdminRemovedToList(new AdminRemovedToListEvent(this, string));
		}
		
		
	}
	
	private void fireAddComponentToList(String name) {
		ListComponentListener[] listenerList = (ListComponentListener[])listeners.getListeners(ListComponentListener.class);
		
		for(ListComponentListener listener : listenerList){
			listener.ComponentAddedToList(new ComponentAddedToListEvent(this, name));
		}
		
		
	}

	private void fireRemoveComponentToList(String string) {
		ListComponentListener[] listenerList = (ListComponentListener[])listeners.getListeners(ListComponentListener.class);
		
		for(ListComponentListener listener : listenerList){
			listener.ComponentRemovedToList(new ComponentRemovedToListEvent(this, string));
		}
		
		
	}
	
}
